home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
335_01
/
as1805.y
< prev
next >
Wrap
Text File
|
1990-12-02
|
33KB
|
1,487 lines
%{
/*
HEADER: ;
TITLE: Frankenstein Cross Assemblers;
VERSION: 2.0;
DESCRIPTION: " Reconfigurable Cross-assembler producing Intel (TM)
Hex format object records. ";
KEYWORDS: cross-assemblers, 1805, 2650, 6301, 6502, 6805, 6809,
6811, tms7000, 8048, 8051, 8096, z8, z80;
SYSTEM: UNIX, MS-Dos ;
FILENAME: as1805.y;
WARNINGS: "This software is in the public domain.
Any prior copyright claims are relinquished.
This software is distributed with no warranty whatever.
The author takes no responsibility for the consequences
of its use.
Yacc (or Bison) required to compile." ;
SEE-ALSO: as1805.doc,frasmain.c;
AUTHORS: Mark Zenier;
COMPILERS: Microport Sys V/AT, ATT Yacc, Turbo C V1.5, Bison (CUG disk 285)
(previous versions Xenix, Unisoft 68000 Version 7, Sun 3);
*/
/* RCA 1802 instruction generation file */
/* November 17, 1990 - character set support */
/*
description frame work parser description for framework cross
assemblers
history February 2, 1988
September 11, 1990 - merge table definition
September 12, 1990 - short file names
September 14, 1990 - short variable names
September 17, 1990 - use yylex as external
*/
#include <stdio.h>
#include "frasmdat.h"
#include "fragcon.h"
#define yylex lexintercept
#define CPUMASK 0xc000
#define CPU1802 0x4000
#define CPU1805 0xc000
#define TS1802PLUS 0x4000 /* mask and match values in table */
#define TS1805 0x8000 /* if select value & mask == mask */
#define ST_INH 0x1
#define ST_IMM 0x2
#define ST_EXP 0x4
#define ST_IO 0x1
#define ST_REG 0x1
#define ST_LDN 0x1
#define ST_RLDI 0x1
#define ST_DBNZ 0x1
int cpuselect = CPU1805;
static char genbdef[] = "[1=];";
static char genwdef[] = "[1=]x"; /* x for normal, y for byte rev */
char ignosyn[] = "[Xinvalid syntax for instruction";
char ignosel[] = "[Xinvalid operands/illegal instruction for cpu";
long labelloc;
static int satsub;
int ifstkpt = 0;
int fraifskip = FALSE;
struct symel * endsymbol = SYMNULL;
%}
%union {
int intv;
long longv;
char *strng;
struct symel *symb;
}
%token <intv> KOC_BDEF
%token <intv> KOC_ELSE
%token <intv> KOC_END
%token <intv> KOC_ENDI
%token <intv> KOC_EQU
%token <intv> KOC_IF
%token <intv> KOC_INCLUDE
%token <intv> KOC_ORG
%token <intv> KOC_RESM
%token <intv> KOC_SDEF
%token <intv> KOC_SET
%token <intv> KOC_WDEF
%token <intv> KOC_CHSET
%token <intv> KOC_CHDEF
%token <intv> KOC_CHUSE
%token <intv> KOC_opcode
%token <intv> KOC_ioop
%token <intv> KOC_regop
%token <intv> KOC_ldn
%token <intv> KOC_rldi
%token <intv> KOC_dbnz
%token <longv> CONSTANT
%token EOL
%token KEOP_AND
%token KEOP_DEFINED
%token KEOP_EQ
%token KEOP_GE
%token KEOP_GT
%token KEOP_HIGH
%token KEOP_LE
%token KEOP_LOW
%token KEOP_LT
%token KEOP_MOD
%token KEOP_MUN
%token KEOP_NE
%token KEOP_NOT
%token KEOP_OR
%token KEOP_SHL
%token KEOP_SHR
%token KEOP_XOR
%token KEOP_locctr
%token <symb> LABEL
%token <strng> STRING
%token <symb> SYMBOL
%token KTK_invalid
%right KEOP_HIGH KEOP_LOW
%left KEOP_OR KEOP_XOR
%left KEOP_AND
%right KEOP_NOT
%nonassoc KEOP_GT KEOP_GE KEOP_LE KEOP_LT KEOP_NE KEOP_EQ
%left '+' '-'
%left '*' '/' KEOP_MOD KEOP_SHL KEOP_SHR
%right KEOP_MUN
%type <intv> expr exprlist stringlist
%start file
%%
file : file allline
| allline
;
allline : line EOL
{
clrexpr();
}
| EOL
| error EOL
{
clrexpr();
yyerrok;
}
;
line : LABEL KOC_END
{
endsymbol = $1;
nextreadact = Nra_end;
}
| KOC_END
{
nextreadact = Nra_end;
}
| KOC_INCLUDE STRING
{
if(nextfstk >= FILESTKDPTH)
{
fraerror("include file nesting limit exceeded");
}
else
{
infilestk[nextfstk].fnm = savestring($2,strlen($2));
if( (infilestk[nextfstk].fpt = fopen($2,"r"))
==(FILE *)NULL )
{
fraerror("cannot open include file");
}
else
{
nextreadact = Nra_new;
}
}
}
| LABEL KOC_EQU expr
{
if($1 -> seg == SSG_UNDEF)
{
pevalexpr(0, $3);
if(evalr[0].seg == SSG_ABS)
{
$1 -> seg = SSG_EQU;
$1 -> value = evalr[0].value;
prtequvalue("C: 0x%lx\n",
evalr[0].value);
}
else
{
fraerror(
"noncomputable expression for EQU");
}
}
else
{
fraerror(
"cannot change symbol value with EQU");
}
}
| LABEL KOC_SET expr
{
if($1 -> seg == SSG_UNDEF
|| $1 -> seg == SSG_SET)
{
pevalexpr(0, $3);
if(evalr[0].seg == SSG_ABS)
{
$1 -> seg = SSG_SET;
$1 -> value = evalr[0].value;
prtequvalue("C: 0x%lx\n",
evalr[0].value);
}
else
{
fraerror(
"noncomputable expression for SET");
}
}
else
{
fraerror(
"cannot change symbol value with SET");
}
}
| KOC_IF expr
{
if((++ifstkpt) < IFSTKDEPTH)
{
pevalexpr(0, $2);
if(evalr[0].seg == SSG_ABS)
{
if(evalr[0].value != 0)
{
elseifstk[ifstkpt] = If_Skip;
endifstk[ifstkpt] = If_Active;
}
else
{
fraifskip = TRUE;
elseifstk[ifstkpt] = If_Active;
endifstk[ifstkpt] = If_Active;
}
}
else
{
fraifskip = TRUE;
elseifstk[ifstkpt] = If_Active;
endifstk[ifstkpt] = If_Active;
}
}
else
{
fraerror("IF stack overflow");
}
}
| KOC_IF
{
if(fraifskip)
{
if((++ifstkpt) < IFSTKDEPTH)
{
elseifstk[ifstkpt] = If_Skip;
endifstk[ifstkpt] = If_Skip;
}
else
{
fraerror("IF stack overflow");
}
}
else
{
yyerror("syntax error");
YYERROR;
}
}
| KOC_ELSE
{
switch(elseifstk[ifstkpt])
{
case If_Active:
fraifskip = FALSE;
break;
case If_Skip:
fraifskip = TRUE;
break;
case If_Err:
fraerror("ELSE with no matching if");
break;
}
}
| KOC_ENDI
{
switch(endifstk[ifstkpt])
{
case If_Active:
fraifskip = FALSE;
ifstkpt--;
break;
case If_Skip:
fraifskip = TRUE;
ifstkpt--;
break;
case If_Err:
fraerror("ENDI with no matching if");
break;
}
}
| LABEL KOC_ORG expr
{
pevalexpr(0, $3);
if(evalr[0].seg == SSG_ABS)
{
locctr = labelloc = evalr[0].value;
if($1 -> seg == SSG_UNDEF)
{
$1 -> seg = SSG_ABS;
$1 -> value = labelloc;
}
else
fraerror(
"multiple definition of label");
prtequvalue("C: 0x%lx\n",
evalr[0].value);
}
else
{
fraerror(
"noncomputable expression for ORG");
}
}
| KOC_ORG expr
{
pevalexpr(0, $2);
if(evalr[0].seg == SSG_ABS)
{
locctr = labelloc = evalr[0].value;
prtequvalue("C: 0x%lx\n",
evalr[0].value);
}
else
{
fraerror(
"noncomputable expression for ORG");
}
}
| LABEL KOC_CHSET
{
if($1 -> seg == SSG_UNDEF)
{
$1 -> seg = SSG_EQU;
if( ($1->value = chtcreate()) <= 0)
{
fraerror( "cannot create character translation table");
}
prtequvalue("C: 0x%lx\n", $1 -> value);
}
else
{
fraerror( "multiple definition of label");
}
}
| KOC_CHUSE
{
chtcpoint = (int *) NULL;
prtequvalue("C: 0x%lx\n", 0L);
}
| KOC_CHUSE expr
{
pevalexpr(0, $2);
if( evalr[0].seg == SSG_ABS)
{
if( evalr[0].value == 0)
{
chtcpoint = (int *)NULL;
prtequvalue("C: 0x%lx\n", 0L);
}
else if(evalr[0].value < chtnxalph)
{
chtcpoint = chtatab[evalr[0].value];
prtequvalue("C: 0x%lx\n", evalr[0].value);
}
else
{
fraerror("nonexistent character translation table");
}
}
else
{
fraerror("noncomputable expression");
}
}
| KOC_CHDEF STRING ',' exprlist
{
int findrv, numret, *cha